package com.smart.translator.device;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.media.MediaPlayer;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import com.smart.translator.util.AdpcmDecoder;
import com.smart.translator.util.WavUtil;

public class ClassicBluetoothManager {
    private static final String TAG = "ClassicBT";
    private static final String SPP_TAG = "SPP_DATA"; // 专门用于SPP数据输出的tag
    private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    
    private static ClassicBluetoothManager instance;
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothSocket bluetoothSocket;
    private InputStream inputStream;
    private OutputStream outputStream;
    private boolean isConnected = false;
    private boolean isConnecting = false;
    
    private ExecutorService executorService;
    private Handler mainHandler;
    
    // 新增：ADPCM解码和音频播放相关成员变量
    private AdpcmDecoder adpcmDecoder;
    private ByteArrayOutputStream pcmBuffer;
    private MediaPlayer mediaPlayer;
    private Context context;
    private static final int PCM_SAMPLE_RATE = 8000;
    private static final int PCM_CHANNELS = 1;
    private static final int PCM_BITS = 16;
    private long lastDataTime = 0;
    private static final long DATA_TIMEOUT = 1000; // 1秒无数据则播放
    private Handler audioHandler = new Handler(Looper.getMainLooper());
    private Runnable playAudioRunnable;
    
    private OnConnectionListener connectionListener;
    private OnDataReceivedListener dataReceivedListener;
    
    public interface OnConnectionListener {
        void onConnected(BluetoothDevice device);
        void onDisconnected();
        void onConnectionFailed(String error);
    }
    
    public interface OnDataReceivedListener {
        void onDataReceived(byte[] data);
    }
    
    private ClassicBluetoothManager() {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        executorService = Executors.newCachedThreadPool();
        mainHandler = new Handler(Looper.getMainLooper());
        
        // 初始化ADPCM解码和音频播放组件
        adpcmDecoder = new AdpcmDecoder();
        pcmBuffer = new ByteArrayOutputStream();
        mediaPlayer = new MediaPlayer();
    }
    
    public static ClassicBluetoothManager getInstance() {
        if (instance == null) {
            instance = new ClassicBluetoothManager();
        }
        return instance;
    }
    
    public void setConnectionListener(OnConnectionListener listener) {
        this.connectionListener = listener;
    }
    
    public void setDataReceivedListener(OnDataReceivedListener listener) {
        this.dataReceivedListener = listener;
    }
    
    public void setContext(Context context) {
        this.context = context;
    }
    
    public boolean isConnected() {
        return isConnected;
    }
    
    public boolean isConnecting() {
        return isConnecting;
    }
    
    public void connectToDevice(BluetoothDevice device) {
        if (isConnecting || isConnected) {
            Log.w(TAG, "连接已在进行中或已连接");
            return;
        }
        
        isConnecting = true;
        Log.d(TAG, "开始连接SPP设备: " + device.getName() + " (" + device.getAddress() + ")");
        
        executorService.execute(() -> {
            try {
                // 直接创建SPP RFCOMM socket
                bluetoothSocket = device.createRfcommSocketToServiceRecord(SPP_UUID);
                Log.d(TAG, "创建SPP socket成功，开始连接...");
                
                // 连接SPP
                bluetoothSocket.connect();
                Log.d(TAG, "SPP连接成功");
                
                // 获取输入输出流
                inputStream = bluetoothSocket.getInputStream();
                outputStream = bluetoothSocket.getOutputStream();
                
                isConnected = true;
                isConnecting = false;
                
                Log.d(TAG, "SPP数据传输通道建立成功");
                
                // 在主线程通知连接成功
                mainHandler.post(() -> {
                    if (connectionListener != null) {
                        connectionListener.onConnected(device);
                    }
                });
                
                // 开始监听SPP数据
                startDataListener();
                
            } catch (IOException e) {
                Log.e(TAG, "SPP连接失败", e);
                isConnecting = false;
                closeConnection();
                
                String errorMsg = "SPP连接失败: " + e.getMessage();
                Log.e(TAG, errorMsg);
                
                mainHandler.post(() -> {
                    if (connectionListener != null) {
                        connectionListener.onConnectionFailed(errorMsg);
                    }
                });
            }
        });
    }
    
    public void disconnect() {
        Log.d(TAG, "断开连接");
        closeConnection();
        
        mainHandler.post(() -> {
            if (connectionListener != null) {
                connectionListener.onDisconnected();
            }
        });
    }
    
    private void closeConnection() {
        isConnected = false;
        isConnecting = false;
        
        try {
            if (inputStream != null) {
                inputStream.close();
                inputStream = null;
            }
            if (outputStream != null) {
                outputStream.close();
                outputStream = null;
            }
            if (bluetoothSocket != null) {
                bluetoothSocket.close();
                bluetoothSocket = null;
            }
        } catch (IOException e) {
            Log.e(TAG, "关闭连接时出错", e);
        }
    }
    
    public boolean sendData(byte[] data) {
        if (!isConnected || outputStream == null) {
            Log.w(TAG, "设备未连接，无法发送数据");
            return false;
        }
        
        executorService.execute(() -> {
            try {
                outputStream.write(data);
                outputStream.flush();
                Log.d(SPP_TAG, "SPP数据发送成功: " + bytesToHex(data));
            } catch (IOException e) {
                Log.e(TAG, "发送数据失败", e);
                // 发送失败，断开连接
                disconnect();
            }
        });
        
        return true;
    }
    
    private void startDataListener() {
        executorService.execute(() -> {
            byte[] buffer = new byte[1024];
            int bytes;
            
            while (isConnected && inputStream != null) {
                try {
                    bytes = inputStream.read(buffer);
                    if (bytes > 0) {
                        byte[] receivedData = new byte[bytes];
                        System.arraycopy(buffer, 0, receivedData, 0, bytes);
                        
                        // 打印所有接收到的SPP数据
                        String hexData = bytesToHex(receivedData);
                        String dataString = new String(receivedData);
                        
                        Log.d(SPP_TAG, "=== SPP数据接收 ===");
                        Log.d(SPP_TAG, "数据长度: " + bytes + " 字节");
                        Log.d(SPP_TAG, "十六进制: " + hexData);
                        Log.d(SPP_TAG, "字符串: " + dataString);
                        Log.d(SPP_TAG, "====================");
                        
                        // 新增：ADPCM解码和音频播放逻辑
                        handleSppAudioData(receivedData);
                        
                        // 在主线程通知数据接收
                        mainHandler.post(() -> {
                            if (dataReceivedListener != null) {
                                dataReceivedListener.onDataReceived(receivedData);
                            }
                        });
                    }
                } catch (IOException e) {
                    Log.e(TAG, "读取SPP数据失败", e);
                    break;
                }
            }
            
            // 如果循环退出，说明连接已断开
            if (isConnected) {
                disconnect();
            }
        });
    }
    
    private String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }
    
    public void destroy() {
        disconnect();
        if (executorService != null) {
            executorService.shutdown();
        }
        
        // 清理音频相关资源
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
        if (audioHandler != null && playAudioRunnable != null) {
            audioHandler.removeCallbacks(playAudioRunnable);
        }
    }
    
    // 新增：处理SPP音频数据
    private void handleSppAudioData(byte[] data) {
        if (data == null || data.length == 0) {
            Log.w(SPP_TAG, "SPP音频数据为空，跳过解码");
            return;
        }
        
        try {
            // 更新最后接收数据时间
            lastDataTime = System.currentTimeMillis();
            
            // 取消之前的播放任务
            if (playAudioRunnable != null) {
                audioHandler.removeCallbacks(playAudioRunnable);
            }
            
            // 重置ADPCM解码器状态，避免状态累积错误
            adpcmDecoder.reset();
            
            // 直接解码ADPCM数据（无帧头）
            short[] pcmSamples = decodeAdpcmData(data);
            if (pcmSamples.length > 0) {
                // 转换为字节数组
                byte[] pcmBytes = shortArrayToByteArray(pcmSamples);
                
                // 追加到PCM缓冲区
                pcmBuffer.write(pcmBytes);
                
                Log.d(SPP_TAG, "ADPCM解码成功: " + pcmSamples.length + " 个PCM样本");
                Log.d(SPP_TAG, "PCM字节数: " + pcmBytes.length + " 字节");
                Log.d(SPP_TAG, "缓冲区总大小: " + pcmBuffer.size() + " 字节");
                
                // 设置延迟播放任务
                playAudioRunnable = new Runnable() {
                    @Override
                    public void run() {
                        playDecodedAudio();
                    }
                };
                audioHandler.postDelayed(playAudioRunnable, DATA_TIMEOUT);
            } else {
                Log.w(SPP_TAG, "ADPCM解码结果为空");
            }
            
        } catch (Exception e) {
            Log.e(SPP_TAG, "ADPCM解码失败", e);
        }
    }
    
    // 新增：播放解码后的音频
    private void playDecodedAudio() {
        if (pcmBuffer.size() == 0) {
            Log.w(SPP_TAG, "PCM缓冲区为空，无法播放");
            return;
        }
        
        try {
            // 获取PCM数据
            byte[] pcmData = pcmBuffer.toByteArray();
            Log.d(SPP_TAG, "准备生成WAV文件，PCM数据大小: " + pcmData.length + " 字节");
            
            // 转换为WAV格式
            byte[] wavData = WavUtil.pcmToWav(pcmData, PCM_SAMPLE_RATE, PCM_CHANNELS, PCM_BITS);
            Log.d(SPP_TAG, "WAV数据生成完成，大小: " + wavData.length + " 字节");
            
            // 保存WAV文件
            if (context != null) {
                File wavFile = new File(context.getExternalFilesDir(null), "spp_audio.wav");
                
                // 检查目录是否存在
                File directory = wavFile.getParentFile();
                if (!directory.exists()) {
                    boolean created = directory.mkdirs();
                    Log.d(SPP_TAG, "创建目录: " + directory.getAbsolutePath() + ", 结果: " + created);
                }
                
                // 写入文件
                FileOutputStream fos = new FileOutputStream(wavFile);
                fos.write(wavData);
                fos.flush();
                fos.close();
                
                // 验证文件是否真的保存了
                if (wavFile.exists()) {
                    long fileSize = wavFile.length();
                    Log.d(SPP_TAG, "WAV文件保存成功: " + wavFile.getAbsolutePath());
                    Log.d(SPP_TAG, "文件大小: " + fileSize + " 字节");
                    
                    if (fileSize > 0) {
                        // 播放音频
                        playWavFile(wavFile);
                    } else {
                        Log.e(SPP_TAG, "WAV文件大小为0，保存失败");
                    }
                } else {
                    Log.e(SPP_TAG, "WAV文件不存在，保存失败");
                }
            } else {
                Log.e(SPP_TAG, "Context为空，无法保存WAV文件");
            }
            
            // 清空缓冲区
            pcmBuffer.reset();
            
        } catch (Exception e) {
            Log.e(SPP_TAG, "播放音频失败", e);
            e.printStackTrace();
        }
    }
    
    // 新增：播放WAV文件
    private void playWavFile(File wavFile) {
        try {
            if (mediaPlayer != null) {
                mediaPlayer.release();
            }
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource(wavFile.getAbsolutePath());
            mediaPlayer.prepare();
            mediaPlayer.start();
            
            Log.d(SPP_TAG, "开始播放SPP音频文件");
            
            // 播放完成后释放资源
            mediaPlayer.setOnCompletionListener(mp -> {
                Log.d(SPP_TAG, "SPP音频播放完成");
                mp.release();
            });
            
        } catch (Exception e) {
            Log.e(SPP_TAG, "播放WAV文件失败", e);
        }
    }
    
    // 新增：short数组转byte数组
    private byte[] shortArrayToByteArray(short[] arr) {
        byte[] out = new byte[arr.length * 2];
        for (int i = 0; i < arr.length; i++) {
            out[i * 2] = (byte) (arr[i] & 0xFF);
            out[i * 2 + 1] = (byte) ((arr[i] >> 8) & 0xFF);
        }
        return out;
    }
    
    // 新增：直接解码ADPCM数据（无帧头）
    private short[] decodeAdpcmData(byte[] adpcmData) {
        if (adpcmData == null || adpcmData.length == 0) {
            Log.w(SPP_TAG, "ADPCM数据为空");
            return new short[0];
        }
        
        Log.d(SPP_TAG, "开始解码ADPCM数据，长度: " + adpcmData.length + " 字节");
        
        // 验证ADPCM数据的前几个字节，检查是否为有效的ADPCM数据
        if (adpcmData.length >= 4) {
            Log.d(SPP_TAG, "ADPCM数据前4字节: " + 
                String.format("%02X %02X %02X %02X", 
                    adpcmData[0], adpcmData[1], adpcmData[2], adpcmData[3]));
        }
        
        // 使用AdpcmDecoder的decodeWithoutHeader方法
        short[] pcmSamples = adpcmDecoder.decodeWithoutHeader(adpcmData);
        
        Log.d(SPP_TAG, "ADPCM解码完成，输出PCM样本数: " + pcmSamples.length);
        
        // 检查解码结果的合理性
        if (pcmSamples.length > 0) {
            short min = pcmSamples[0], max = pcmSamples[0];
            for (short sample : pcmSamples) {
                if (sample < min) min = sample;
                if (sample > max) max = sample;
            }
            Log.d(SPP_TAG, "PCM样本范围: " + min + " 到 " + max);
        }
        
        return pcmSamples;
    }
    
    // 新增：检查WAV文件是否存在
    public boolean checkWavFileExists() {
        if (context == null) {
            Log.e(TAG, "Context为空，无法检查文件");
            return false;
        }
        
        File wavFile = new File(context.getExternalFilesDir(null), "spp_audio.wav");
        boolean exists = wavFile.exists();
        long fileSize = exists ? wavFile.length() : 0;
        
        Log.d(TAG, "WAV文件检查: " + wavFile.getAbsolutePath());
        Log.d(TAG, "文件存在: " + exists + ", 文件大小: " + fileSize + " 字节");
        
        return exists && fileSize > 0;
    }
} 